﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using VisionFrame.Models;

namespace VisionFrame.ViewModels
{
    internal class MainViewModel : ObservableObject
    {
        #region 组件类别处理
        private CatalogModel _currentCatalog;

        public CatalogModel CurrentCatalog
        {
            get { return _currentCatalog; }
            set { SetProperty<CatalogModel>(ref _currentCatalog, value); }
        }


        public List<CatalogModel> CatalogList { get; set; } =
            new List<CatalogModel>();

        public ICommand CatalogItemCommand { get; set; }
        public ICommand ComponentItemCommand { get; set; }
        #endregion

        public ObservableCollection<FlowTabViewModel> FlowTabList { get; set; } =
            new ObservableCollection<FlowTabViewModel>()
            {
                
            };

        public ICommand NewFlowCommand { get; set; }
        public ICommand CloseFlowTabCommand { get; set; }

        public ICommand SaveFlowCommand { get; set; }
        public ICommand OpenFlowCommand { get; set; }

        public ICommand MaximizeCommand { get; }
        public ICommand MinimizeCommand { get; }
        public MainViewModel()
        {
            #region 组件列表数据初始化
            CatalogList.Add(new CatalogModel()
            {
                IsSelected = true,
                Icon = "\ue9ed",
                Name = "图像采集",
                Description = "获取图像方式",
                Components = new List<ComponentModel>
                {
                    new ComponentModel{ Icon="\ue604",
                        Name="文件夹",
                        TargetNode="ImageCapture;ImageCapture.FolderImageNode",
                        TargetModel="ImageCapture;ImageCapture.FolderImageNodeModel",
                        W=150,
                        H=34
                        },
                    new ComponentModel{ Icon="\ue621",Name="Halcon",
                        TargetNode="ImageCapture;ImageCapture.HalconImageNode",
                        TargetModel="ImageCapture;ImageCapture.HalconImageNodeModel",
                        W=150,
                        H=34},
                }
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue9ee",
                Name = "图像处理",
                Description = "获取图像方式获取图像方式获取图像方式",
                Components = new List<ComponentModel>
                {
                    new ComponentModel{ Name="图像保存"},
                    new ComponentModel{ Name="图像显示",Icon="\ue9ee",
                    TargetNode="ImageProcess;ImageProcess.ImageShowNode",
                        TargetModel="ImageProcess;ImageProcess.ImageShowNodeModel",
                        W=150,
                        H=34}
                }
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ueb05",
                Name = "设备通信",
                Description = "获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue636",
                Name = "图像坐标变换",
                Description = "获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue73f",
                Name = "逻辑控制",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式",
                Components = new List<ComponentModel>
                {
                    new ComponentModel{ Name="加法",Icon="\ue74d",
                        TargetNode="LogicControl;LogicControl.AddNode",
                        TargetModel="LogicControl;LogicControl.AddNodeModel",
                        W=150,
                        H=34
                    },
                    new ComponentModel{ Name="IF判断",Icon="\ue71d",
                        TargetNode="LogicControl;LogicControl.DecisionNode",
                        TargetModel="LogicControl;LogicControl.DecisionNodeModel",
                        W=120,
                        H=45
                    }
                }
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue8a4",
                Name = "标定工具",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue86e",
                Name = "逻辑控制",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue644",
                Name = "阈值分割",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue66d",
                Name = "几何测量",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue608",
                Name = "模板匹配",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue712",
                Name = "图像内容识别",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式"
            });
            CatalogList.Add(new CatalogModel()
            {
                Icon = "\ue73c",
                Name = "变量工具",
                Description = "获取图像方式获取图像方式获取图像方式获取图像方式"
            });
            #endregion
            CurrentCatalog = CatalogList[0];

            CatalogItemCommand =
                new RelayCommand<CatalogModel>(model => CurrentCatalog = model);

            ComponentItemCommand = new RelayCommand<object>(OnComponentItem);

            NewFlowCommand = new RelayCommand(DoNewFlow);
            CloseFlowTabCommand = new RelayCommand<object>(DoCloseFlowTab);

            SaveFlowCommand = new RelayCommand(DoSaveFlow);

            OpenFlowCommand = new RelayCommand(DoOpenFlow);

            MaximizeCommand = new RelayCommand(() =>
            {
                var window = Application.Current.MainWindow;
                if (window.WindowState==WindowState.Normal)
                {
                    window.WindowState = WindowState.Maximized;
                }
                else
                {
                    window.WindowState = WindowState.Normal;
                }
                
            });

            MinimizeCommand = new RelayCommand(() =>
            {
                var window = Application.Current.MainWindow;
                window.WindowState = WindowState.Minimized;
            });
        }

        private void OnComponentItem(object obj)
        {
            // 组件标签触发的   
            // 当前点击标签的数据源==标签的Model
            var model = (obj as FrameworkElement).DataContext;
            // 完成拖拽对象的创建
            DragDrop.DoDragDrop((DependencyObject)obj, model, DragDropEffects.Copy);
        }

        #region Tab操作
        private async void DoNewFlow()
        {
            string title = "新建流程";
            string temp = "";
            await Task.Run(() =>
            {
                int i = 1;
                do
                {
                    temp = title + $"({i})";
                    i++;
                } while (FlowTabList.ToList().Exists(f => f.Title == temp));
                //title = temp;
            });
            FlowTabList.Add(new FlowTabViewModel
            {
                Title = temp
            });
        }

        private void DoCloseFlowTab(object obj)
        {
            if (obj is FlowTabViewModel vm)
            {
                FlowTabList.Remove(vm);
            }
            else
            {
                if (obj.ToString() == "1")
                {
                    // 关闭当前Tab
                    vm = FlowTabList.FirstOrDefault(f => f.IsCurrent);
                    if (vm != null)
                        FlowTabList.Remove(vm);
                }
                else if (obj.ToString() == "2")
                {
                    // 关闭其他
                    var vms = FlowTabList.Where(f => !f.IsCurrent);
                    do
                    {
                        FlowTabList.Remove(vms.First());
                    } while (vms.Any());
                }
            }
        }
        #endregion

        private void DoSaveFlow()
        {
            var flow = FlowTabList.FirstOrDefault(f => f.IsCurrent);
            if (flow == null) return;

            flow.Save();
        }

        private void DoOpenFlow()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "流程文件(*.flw)|*.flw";
            dialog.Title = "选择流程文件";
            if (dialog.ShowDialog() == true)
            {
                string fileName = dialog.FileName;


                // 检查当前所有Tab中有没有这个文件
                var flow = FlowTabList.FirstOrDefault(f =>
                      !string.IsNullOrEmpty(f.FilePath) &&
                      f.FilePath.ToLower() == fileName.ToLower()
                      );
                if (flow != null)
                {
                    flow.IsCurrent = true;
                    return;
                }


                string json = System.IO.File.ReadAllText(fileName);

                string[] jsons = json.Split("@#$#@");
                if (jsons.Length != 4) return;

                var node = System.Text.Json.JsonSerializer.Deserialize<List<Base.NodeModelBase>>(jsons[1]);
                var link = System.Text.Json.JsonSerializer.Deserialize<List<LinkModel>>(jsons[2]);
                var arg = System.Text.Json.JsonSerializer.Deserialize<List<Base.Models.FlowArgModel>>(jsons[3]);

                FlowTabList.Add(new FlowTabViewModel
                {
                    IsCurrent = true,
                    Title = jsons[0],
                    NodeList = new ObservableCollection<Base.NodeModelBase>(node),
                    LinkList = new ObservableCollection<LinkModel>(link),
                    ArgumentList = new ObservableCollection<Base.Models.FlowArgModel>(arg),
                    FilePath = fileName
                });
            }
        }
    }
}
